from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from passlib.context import CryptContext
from fastapi import HTTPException, status, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from models.database import get_db_connection
from config import settings
import mysql.connector

# 从配置中获取JWT设置
SECRET_KEY = settings.SECRET_KEY
ALGORITHM = settings.ALGORITHM
ACCESS_TOKEN_EXPIRE_MINUTES = settings.ACCESS_TOKEN_EXPIRE_MINUTES

# 密码加密上下文
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# HTTP Bearer认证
security = HTTPBearer()


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    return pwd_context.verify(plain_password, hashed_password)


def get_password_hash(password: str) -> str:
    """生成密码哈希"""
    return pwd_context.hash(password)


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """创建JWT访问令牌"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)

    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """获取当前用户"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无效的认证凭证",
        headers={"WWW-Authenticate": "Bearer"},
    )

    try:
        # 解码JWT令牌
        payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
        user_id: int = payload.get("user_id")
        user_name: str = payload.get("user_name")

        if user_id is None or user_name is None:
            raise credentials_exception

    except JWTError:
        raise credentials_exception

    # 验证用户是否仍然存在
    connection = get_db_connection()
    if not connection:
        raise HTTPException(status_code=500, detail="数据库连接失败")

    try:
        cursor = connection.cursor(dictionary=True)
        cursor.execute(
            "SELECT user_id, user_name FROM user WHERE user_id = %s",
            (user_id,)
        )
        user = cursor.fetchone()

        if user is None:
            raise credentials_exception

        return {"user_id": user["user_id"], "user_name": user["user_name"]}

    except mysql.connector.Error as e:
        raise HTTPException(status_code=500, detail=f"数据库错误: {e}")
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()


async def get_current_active_user(current_user: dict = Depends(get_current_user)):
    """获取当前活跃用户"""
    # 这里可以添加额外的用户状态检查
    # 例如：检查用户是否被禁用、是否已验证等
    return current_user


# 可选：添加令牌验证函数
def verify_token(token: str) -> Optional[dict]:
    """验证令牌并返回payload"""
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        return payload
    except JWTError:
        return None


# 可选：添加密码强度验证
def validate_password_strength(password: str) -> bool:
    """验证密码强度"""
    if len(password) < 6:
        return False
    # 可以添加更多密码强度规则
    return True